#ifndef __CONDITION_HPP__
#define __CONDITION_HPP__

#include <time.h>
#include "threadobject.hpp"

namespace purewell
{

class PWCondition;
class PWConditionAttribute;
class PWMutex;

//! \brief Thread condition.
class PWCondition : PWThreadObject
{
public:
	//! \brief Create condition.
	//! \param[in] pattr Attribution of condition.
	//! \return On success, condition pointer or NULL.
	static PWCondition* create(const PWConditionAttribute* pattr = NULL);

	//! \brief Release condition.
	//! \param[in] obj Condition pointer to release.
	static void release(PWCondition* obj);

public:
	//! \brief Send signal.
	void signal(void);

	//! \brief Broadcast signal.
	void broadcast(void);

	//! \brief Wait for signal.
	//! \param[in] mutex Mutex object.
	void wait(PWMutex& mutex);

	//! \brief Wait for signal in time.
	//! \param[in] mutex Mutex object.
	//! \param[in] msec Time to wait.
	//! \return On success to wait, true.
	bool wait(PWMutex& mutex, size_t msec);

	//! \brief Wait for signal in time.
	//! \param[in] mutex Mutex object.
	//! \param[in] ts Time to wait.
	//! \return On success to wait, true.
	bool wait(PWMutex& mutex, struct timespec& ts);

private:
	explicit PWCondition();
	virtual ~PWCondition();

};

//! \brief Thread condtion attribute.
class PWConditionAttribute : public PWThreadObject
{
public:
	//! \brief Create condition attribution.
	//! \return On success pointer of condition attribution, or NULL.
	static PWConditionAttribute* create(void);

	//! \brief Release condition attribution.
	//! \param[in] obj Condition attribution object to release.
	static void release(PWConditionAttribute* obj);

public:
	//! \brief Set process share option.
	//! \param[in] value If set true, condition will be shared.
	bool setProcessShared(bool value);

	//! \brief Get process share option.
	//! \return On process shared, true.
	bool getProcessShared(void) const;

private:
	explicit PWConditionAttribute();
	virtual ~PWConditionAttribute();
};

};//namespace purewell

#endif//!__CONDITION_HPP__

